home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / RTrace 1.0 / source / csg_4.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-17  |  4.3 KB  |  129 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Copyright (c) 1988, 1992 Antonio Costa, INESC-Norte.
  3.  * All rights reserved.
  4.  *
  5.  * This code received contributions from the following people:
  6.  *
  7.  *  Roman Kuchkuda      - basic ray tracer
  8.  *  Mark VandeWettering - MTV ray tracer
  9.  *  Augusto Sousa       - overall, shading model
  10.  *  Craig Kolb          - CSG
  11.  *
  12.  * Redistribution and use in source and binary forms are permitted
  13.  * provided that the above copyright notice and this paragraph are
  14.  * duplicated in all such forms and that any documentation,
  15.  * advertising materials, and other materials related to such
  16.  * distribution and use acknowledge that the software was developed
  17.  * by Antonio Costa, at INESC-Norte. The name of the author and
  18.  * INESC-Norte may not be used to endorse or promote products derived
  19.  * from this software without specific prior written permission.
  20.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  21.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  22.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  23.  */
  24. #include "defs.h"
  25. #include "extern.h"
  26. #include "csg.h"
  27.  
  28. /**********************************************************************
  29.  *    RAY TRACING - CSG - Version 7.3.1                               *
  30.  *                                                                    *
  31.  *    MADE BY    : Antonio Costa, INESC-Norte, June 1992              *
  32.  *    MODIFIED BY: Antonio Costa, INESC-Norte, July 1992              *
  33.  **********************************************************************/
  34.  
  35. /***** CSG *****/
  36. extern tree_struct tree;
  37. extern hit_struct hit_global;
  38.  
  39. real
  40. csg_intersect(position, vector, csg_object)
  41.   xyz_ptr         position, vector;
  42.   object_ptr      csg_object;
  43. {
  44.   real            distance;
  45.   REG real        distance1, distance2;
  46.   xyz_struct      new_position, new_vector;
  47.   csg_ptr         csg;
  48.   hit_ptr         hit1, hit2, hit;
  49.   hit_struct      hit1_list;
  50.   static hit_struct hit2_list;
  51.  
  52.   if (csg_object->transf != NULL)
  53.   {
  54.     transform(csg_object->transf, position, &new_position);
  55.     transform_vector(csg_object->transf, position, vector, &new_position,
  56.                      &new_vector);
  57.     NORMALIZE(new_vector);
  58.   } else
  59.   {
  60.     STRUCT_ASSIGN(new_position, *position);
  61.     STRUCT_ASSIGN(new_vector, *vector);
  62.   }
  63.   REALINC(csg_tests);
  64.   csg = (csg_ptr) csg_object->data;
  65.   /* CSG intersection */
  66.   hit1 = &hit1_list;
  67.   hit2 = &hit2_list;
  68.   hit1->nodes = 0;
  69.   hit2->nodes = 0;
  70.   tree.depth = 0;
  71.   SAVE_TREE_PATH(PATH_LEFT);
  72.   distance1 = object_intersect(object[csg->left], &new_position,
  73.                    &new_vector, hit1, threshold_distance);
  74.   if ((distance1 < threshold_distance) AND((csg->op == CSG_SUBTRACTION)
  75.       OR(csg->op == CSG_INTERSECTION)))
  76.     return 0.0;
  77.   SAVE_TREE_PATH(PATH_RIGHT);
  78.   distance2 = object_intersect(object[csg->right], &new_position,
  79.                        &new_vector, hit2, threshold_distance);
  80.   if ((distance2 < threshold_distance) AND((csg->op == CSG_INTERSECTION)
  81.       OR((hit1->nodes == 0) AND(csg->op == CSG_UNION))))
  82.     return 0.0;
  83.   if (distance1 < threshold_distance)
  84.     distance1 = INFINITY;
  85.   if (distance2 < threshold_distance)
  86.     distance2 = INFINITY;
  87.   if ((distance1 > distance2) AND((csg->op == CSG_UNION)
  88.       OR(csg->op == CSG_INTERSECTION)))
  89.   {
  90.     distance = distance2;
  91.     distance2 = distance1;
  92.     distance1 = distance;
  93.     hit1 = &hit2_list;
  94.     hit2 = &hit1_list;
  95.   }
  96.   switch(csg->op)
  97.   {
  98.   case CSG_UNION:
  99.     if (csg_union(&new_position, &new_vector, hit1, hit2,
  100.           distance1, distance2, &hit, &distance))
  101.       return 0.0;
  102.     break;
  103.   case CSG_SUBTRACTION:
  104.     if (csg_subtraction(&new_position, &new_vector, hit1, hit2,
  105.             distance1, distance2, &hit, &distance))
  106.       return 0.0;
  107.     break;
  108.   case CSG_INTERSECTION:
  109.     if (csg_intersection(&new_position, &new_vector, hit1, hit2,
  110.              distance1, distance2, &hit, &distance))
  111.       return 0.0;
  112.     break;
  113.   }
  114.   if (distance < threshold_distance)
  115.     return 0.0;
  116.   csg_copy_hit(hit, &hit_global);
  117.   if (csg_object->transf != NULL)
  118.   {
  119.     csg->position->x = new_position.x + distance * new_vector.x;
  120.     csg->position->y = new_position.y + distance * new_vector.y;
  121.     csg->position->z = new_position.z + distance * new_vector.z;
  122.     return transform_distance(csg_object->inv_transf, distance,
  123.                               &new_position, &new_vector, position);
  124.   } else
  125.     return distance;
  126. }
  127.  
  128.  
  129.